INIT

source("./scripts/startup.R")
The following packages have been unloaded:
ggforestplot, doParallel, iterators, foreach, glmmTMB, broom, tableone, arrow, magrittr, scales, lubridate, ggExtra, ggsci, pheatmap, Biostrings, GenomeInfoDb, XVector, IRanges, S4Vectors, BiocGenerics, ggrepel, data.table, ggpubr, viridis, viridisLite, gggenes, ggforce, glmnet, Matrix, cowplot, forcats, stringr, dplyr, purrr, readr, tidyr, tibble, ggplot2, tidyverse, pacman
Loading required package: pacman

MODELING STAGE

Demonstrate whether a linear regression can be fit or not # INSERT LASSO DISTRIBUTION FOR LOG2 ON z transformed CONT. INPUTS

#p_sub<- p %>% left_join(mcov_samples_filtered) #to add info about coverage

lasso_xy = function(x, y, family = "gaussian") {
  cv_model <- cv.glmnet(x, y, alpha = 1, family = family, nfolds=100)
  plot(cv_model) 
  best_model <- glmnet(x, y, alpha = 1, family = family, lambda = cv_model$lambda.min)
  best_model$dev.ratio
  lasso_coef = coef(best_model) %>% as.matrix() %>% data.frame() %>% rownames_to_column() %>% 
  select(factor=rowname, coefficient=s0) %>% filter(factor!="(Intercept)") %>% 
  arrange(desc(coefficient))
  return(lasso_coef)
}

normalize <- function(x, na.rm = TRUE) {
  scaled = (x- min(x)) /(max(x)-min(x))
    return()
}

LASSO scan the features

Looks like it’s important to remove the HIV and transplant because of sparsity of data.

scan_factors = c('Duration','age18under','age55plus','sex','chronic_lung_disease',
                 'chronic_liver_disease', 'chronic_kidney_disease', 'chronic_heart_disease', 
                 'transplant_patient', 'hiv', 'hypertension', 'diabetes', 'cancer', 'obesity', 
                 'plasma', 'mAb', 'admitted_hospital','vaccine_status',
                 'vocAlpha','vocDelta','collection_month',
                 'surveillance','CT','median_coverage','run', 'PUI')

scale_scan_factors = function(patient_var_tmp, scan_factors) {
  p_sub = patient_var_tmp %>% 
  select(MCoVNumber,lineage,Duration,COLLECTION_DT:last_col(),one_of(scan_factors)) %>% 
  unique %>% as.data.frame()

  p_sub[, colnames(p_sub) %in% scan_factors] 
  p_sub_scaled = p_sub %>% select(one_of(scan_factors)) %>% 
    mutate_if(is.numeric, scale) %>% # scale will z scale it, instead of the normalize fx above which is min max
    cbind(p_sub %>% select(!one_of(scan_factors)))
  return(p_sub_scaled)
}

patient_var_tmp = read_feather("processing/patient_var_tmp.arrow")
scan_factors_trim = scan_factors[!scan_factors %in% c("transplant_patient", "hiv")] 
p_sub_scaled = scale_scan_factors(
  patient_var_tmp %>% filter(n_var < 30 & CT < 26), 
  scan_factors_trim)
y<-log2(p_sub_scaled$n_var+1)
x<-(p_sub_scaled[, colnames(p_sub_scaled) %in% scan_factors_trim]) %>% data.matrix()
lasso_under_30 = lasso_xy(x,y) %>% mutate(cutoff = "n_var_under_30") %>%
  arrange(coefficient) %>% mutate(factor = fct_reorder(factor, coefficient))

lasso_initial_features = lasso_under_30 %>% ggplot(aes(x=factor, y = coefficient)) + 
  geom_bar(stat="identity") + coord_flip()
lasso_initial_features

ggsave("ggsave/lasso_initial_features.pdf", lasso_initial_features, height = 4, width = 3)
admitted_matrix = cbind(x,#[x[,"admitted_hospital"] == 1,], 
                        n_var = normalize(y))
clinical_cor_heatmap = pheatmap(abs(cor(admitted_matrix, method = "spearman")),
                                color = viridis(10), border_color   = NA)

ggsave("ggsave/clinical_cor_heatmap.pdf", clinical_cor_heatmap, height = 6, width = 6)

Demonstrate which features have enough n to be scanned

check_levels = function(x) { return(levels(x) %>% length ==2) }
numeric1 = function(x) { return(as.numeric(x)-1) }

plot_feature_n = function(p_sub_scaled) {
  sum_n = nrow(p_sub_scaled)
  feature_stats_IP = p_sub_scaled %>% select(one_of(scan_factors)) %>% 
    filter(admitted_hospital == 1) %>%
    select_if(is.factor) %>% select_if(check_levels) %>%
    mutate_if(is.factor, numeric1) %>% colSums() %>% 
    data.frame(feature = names(.), IP = .)
    sum_n_IP = feature_stats_IP["admitted_hospital","IP"]

  
  feature_stats_OP = p_sub_scaled %>% select(one_of(scan_factors)) %>% 
    filter(admitted_hospital == 0) %>%
    select_if(is.factor) %>% select_if(check_levels) %>%
    mutate_if(is.factor, numeric1) %>% colSums() %>% 
    data.frame(feature = names(.), OP = .)
  sum_n_OP = sum_n - sum_n_IP
  
  feature_stats = left_join(feature_stats_IP, feature_stats_OP)
  slope = sum_n_OP/sum_n_IP
  feature_n_plot = feature_stats %>% ggplot(aes(x = IP, y = OP, label = feature)) + 
    geom_abline(slope = slope, color = "red", linetype = "dashed") + 
    geom_point() + geom_text_repel() +
    scale_y_continuous( breaks = seq(0,1500,100), limits = c(0,1400),
                       sec.axis = sec_axis(~ . / sum_n_OP, labels = scales::label_percent(),
                                           breaks = seq(0,1,0.1))) + 
    scale_x_continuous( breaks = seq(0,2000,100), guide = guide_axis(angle = 90),
                       sec.axis = sec_axis(~ . / sum_n_IP, labels = scales::label_percent(),
                                           breaks = seq(0,1,0.1))) + theme_pubr() +
    xlab(paste0("Inpatient (n & % of ", sum_n_IP, ")")) +
    ylab(paste0("Outpatient (n & % of ", sum_n_OP, ")"))
  return(feature_n_plot)
}

undated_feature_n_plot = plot_feature_n(p_sub_scaled)
Joining, by = "feature"
julyonwards_feature_n_plot = plot_feature_n(p_sub_scaled %>% 
                                          filter(collection_date>="2021-07-01"))
Joining, by = "feature"
feature_n_plot = ggarrange(undated_feature_n_plot + ggtitle("12/2020 - 11/2021"), 
          julyonwards_feature_n_plot + ggtitle("07/2021 - 11/2021"), align = "h",
          labels = list("A","B"))
feature_n_plot
Warning: ggrepel: 6 unlabeled data points (too many overlaps). Consider increasing max.overlaps

ggsave("ggsave/feature_n_plot.pdf", feature_n_plot, width = 16, height = 8)

PLOTTING COMMANDS PER CT

EXPLORATION OF THE ADMITTED

patient_counts_30 = read_feather("processing/patient_counts_30.arrow")
patient_counts_30 = patient_counts_30 %>% #filter(collection_date >="2021-07-01") %>%
  mutate(admitted_hospital = as.factor(admitted_hospital))

ct_date_plot = function(patient_counts_30, admitted_hospital = "admitted_hospital") {
  plot_admitted = patient_counts_30 %>% 
    ggplot(aes(x = INSTRUMENT_RESULT, y = n_var, color = !!sym(admitted_hospital))) + 
    geom_point(shape = "") +
          geom_density_2d(aes(color = !!sym(admitted_hospital))) + 
    stat_cor(method = "spearman", cor.coef.name = "rho") +
      geom_smooth(se=TRUE) + theme_pubr() + scale_y_continuous(trans="log1p", 
        breaks = c(0,1,2,5,10,15,20,25,30)) +
    scale_x_continuous(limits = c(10,26))
  plot_admitted_marginal_by_ct = ggMarginal(plot_admitted, type = "violin", 
                                            draw_quantiles = c(0,0.25,0.5, 0.75),
             groupColour = TRUE, groupFill = TRUE)

# By Date now:
  plot_admitted_date = patient_counts_30 %>% group_by(admitted_hospital) %>% 
    ggplot(aes(x = collection_date, y = n_var, color = !!sym(admitted_hospital))) + 
    geom_point(shape = "") +
          geom_density_2d(aes(color = !!sym(admitted_hospital))) + 
    stat_cor(method = "spearman", cor.coef.name = "rho") +
      geom_smooth(se = TRUE) + theme_pubr() + scale_y_continuous(trans="log1p", 
                                                               breaks = c(0,1,2,5,10,15,20,25,30))
  plot_admitted_date_marginal = ggMarginal(plot_admitted_date,  groupColour = TRUE, groupFill = TRUE)
  
  plot_admitted_marginal_combined = ggarrange(plot_admitted_marginal_by_ct, 
                                              plot_admitted_date_marginal, align = "h")
}

plot_admitted_marginal_combined = ct_date_plot(patient_counts_30, "admitted_hospital")
Warning: Removed 12 rows containing non-finite values (`stat_density2d()`).
Warning: Removed 12 rows containing non-finite values (`stat_cor()`).
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
Warning: Removed 12 rows containing non-finite values (`stat_smooth()`).
Warning: Removed 12 rows containing non-finite values (`stat_density2d()`).
Warning: Removed 12 rows containing non-finite values (`stat_cor()`).
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
Warning: Removed 12 rows containing non-finite values (`stat_smooth()`).
Warning: Removed 12 rows containing missing values (`geom_point()`).
Warning: `position_dodge()` requires non-overlapping x intervals
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
plot_admitted_marginal_combined

ggsave("ggsave/plot_admitted_marginal_combined.pdf", 
       plot_admitted_marginal_combined, height = 4.5, width = 9)

OTHER FACTORS

# VACCINATION GROUPS HISTOGRAM
vaccine_by_date_hist = patient_counts_30 %>% select(collection_month, vaccine_status, admitted_hospital) %>% 
  filter(vaccine_status == 1) %>% ggplot(aes(x = collection_month)) + 
  geom_histogram(stat="count") + 
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),
        plot.background = element_rect(colour = "black", fill=NA, linewidth =2)) +
  ylab("vaccine count")
Warning in geom_histogram(stat = "count"): Ignoring unknown parameters: `binwidth`, `bins`, and `pad`
vaccine_by_date_hist

ggsave("ggsave/vaccine_by_date_hist.pdf", vaccine_by_date_hist, height = 2, width = 2)
Warning: 'mode(bg)' differs between new and previous
     ==> NOT changing 'bg'
# ADMITTED GROUPS HISTOGRAM
patient_counts_30 %>% select(collection_month, vaccine_status, admitted_hospital) %>%
  filter(admitted_hospital == 1) %>% ggplot(aes(x = collection_month)) + 
  geom_histogram(stat="count")
Warning in geom_histogram(stat = "count"): Ignoring unknown parameters: `binwidth`, `bins`, and `pad`

# Load in the TOTAL HISTOGRAM
lineages_histogram = readRDS("ggsave/lineages_figure.rds")
# combine the histograms
n_vax_admit = patient_counts_30 %>% select(COLLECTION_DT, vaccine_status, admitted_hospital) %>%
   mutate(month = floor_date(COLLECTION_DT, "month")) %>% group_by(month) %>%
  summarize(vaccinated = sum(as.numeric(as.character(vaccine_status))), 
            hospitalized = sum(as.numeric(as.character(admitted_hospital)))) %>%
   pivot_longer(!month, names_to = "trends", values_to = "count")

lineages_histogram_vax_hosp = lineages_histogram +  
  geom_line(data = n_vax_admit, aes(month, count, color = trends, linetype = trends)) +
  scale_color_manual(values = c("grey10", "black")) + theme(legend.position = "right")
# save the output
ggsave("ggsave/lineages_histogram_vax_hosp.pdf", lineages_histogram_vax_hosp, height = 4, width = 4)
# CT VACCINATED
plot_vaccinated_marginal_by_ct = ct_date_plot(patient_counts_30 %>%
                                                filter(collection_date >="2021-07-01" & admitted_hospital == 1), "vaccine_status")
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Warning: `position_dodge()` requires non-overlapping x intervals
`position_dodge()` requires non-overlapping x intervals
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
plot_vaccinated_marginal_by_ct

ggsave("ggsave/plot_vaccinated_marginal_by_ct.pdf", plot_vaccinated_marginal_by_ct, height = 5, width = 5)
# cancer
plot_cancer_marginal_by_ct = ct_date_plot(patient_counts_30 %>%
                                                filter(collection_date <="2021-07-01"), "cancer")
Warning: Removed 11 rows containing non-finite values (`stat_density2d()`).
Warning: Removed 11 rows containing non-finite values (`stat_cor()`).
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
Warning: Removed 11 rows containing non-finite values (`stat_smooth()`).
Warning: Removed 11 rows containing non-finite values (`stat_density2d()`).
Warning: Removed 11 rows containing non-finite values (`stat_cor()`).
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
Warning: Removed 11 rows containing non-finite values (`stat_smooth()`).
Warning: Removed 11 rows containing missing values (`geom_point()`).
Warning: `position_dodge()` requires non-overlapping x intervals
`position_dodge()` requires non-overlapping x intervals
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
plot_cancer_marginal_by_ct

test = ct_date_plot(patient_counts_30, "cancer")
Warning: Removed 12 rows containing non-finite values (`stat_density2d()`).
Warning: Removed 12 rows containing non-finite values (`stat_cor()`).
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
Warning: Removed 12 rows containing non-finite values (`stat_smooth()`).
Warning: Removed 12 rows containing non-finite values (`stat_density2d()`).
Warning: Removed 12 rows containing non-finite values (`stat_cor()`).
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
Warning: Removed 12 rows containing non-finite values (`stat_smooth()`).
Warning: Removed 12 rows containing missing values (`geom_point()`).
Warning: `position_dodge()` requires non-overlapping x intervals
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
test

# VACCINATION GROUPS WITH CONTROL OVER THE TIME & OUTPATIENT STATUS
plot_vaccinated = patient_counts_30 %>%
  filter(collection_date>="2021-07-01") %>% 
  filter(admitted_hospital == 1) %>% 
  group_by(mAb) %>% 
  ggplot(aes(x = INSTRUMENT_RESULT, y = n_var, color = mAb)) + 
  geom_point(shape = "") +
        geom_density_2d(aes(color = mAb)) + stat_cor(method = "spearman", cor.coef.name = "rho") +
    geom_smooth(se=TRUE) + theme_pubr() + scale_y_continuous(trans="log1p", 
                                                             breaks = c(0,1,2,5,10,15,20,25,30)) +
    scale_x_continuous(limits = c(10,26))

    plot_vaccinated_marginal_by_ct = ggMarginal(plot_vaccinated, type = "boxplot", 
                                            draw_quantiles = c(0,0.25,0.5, 0.75),
             groupColour = TRUE, groupFill = TRUE)
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Warning in (function (mapping = NULL, data = NULL, stat = "boxplot", position = "dodge2", : Ignoring unknown parameters: `draw_quantiles`
Ignoring unknown parameters: `draw_quantiles`
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
plot_vaccinated_marginal_by_ct

#ggsave("ggsave/plot_mAb_marginal_by_ct.pdf", plot_vaccinated_marginal_by_ct, height = 5, width = 5)

Healthcare workers

# HCW GROUPS WITH CONTROL OVER THE TIME & OUTPATIENT STATUS
table(patient_counts_30 %>%  select(admitted_hospital,surveillance))
                 surveillance
admitted_hospital    0    1
                0 2975  682
                1 2048   20
plot_hcw= patient_counts_30 %>% filter(admitted_hospital == 0) %>% filter(collection_date>="2021-07-01") %>%
  group_by(surveillance) %>% 
  ggplot(aes(x = INSTRUMENT_RESULT, y = n_var, color = vaccine_status)) + 
  geom_point(shape = "") +
        geom_density_2d(aes(color = vaccine_status)) + 
  stat_cor(method = "spearman", cor.coef.name = "rho") +
    geom_smooth(se=TRUE) + theme_pubr() + scale_y_continuous(trans="log1p", 
                                                             breaks = c(0,1,2,5,10,15,20,25,30))
((
  plot_hcw_marginal_by_ct = ggMarginal(plot_hcw, type = "violin", 
                                            draw_quantiles = c(0,0.25,0.5, 0.75),
             groupColour = TRUE, groupFill = TRUE)
))
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Warning: `position_dodge()` requires non-overlapping x intervals

LS0tCnRpdGxlOiAiT2RkcyBSYXRpb3MiCm91dHB1dDogaHRtbF9ub3RlYm9vawoKLS0tCgojIElOSVQKYGBge3J9CnNvdXJjZSgiLi9zY3JpcHRzL3N0YXJ0dXAuUiIpCmBgYAojIE1PREVMSU5HIFNUQUdFCgpEZW1vbnN0cmF0ZSB3aGV0aGVyIGEgbGluZWFyIHJlZ3Jlc3Npb24gY2FuIGJlIGZpdCBvciBub3QKIyBJTlNFUlQgTEFTU08gRElTVFJJQlVUSU9OIEZPUiBMT0cyIE9OIHogdHJhbnNmb3JtZWQgQ09OVC4gSU5QVVRTCgpgYGB7cn0KI3Bfc3ViPC0gcCAlPiUgbGVmdF9qb2luKG1jb3Zfc2FtcGxlc19maWx0ZXJlZCkgI3RvIGFkZCBpbmZvIGFib3V0IGNvdmVyYWdlCgpsYXNzb194eSA9IGZ1bmN0aW9uKHgsIHksIGZhbWlseSA9ICJnYXVzc2lhbiIpIHsKICBjdl9tb2RlbCA8LSBjdi5nbG1uZXQoeCwgeSwgYWxwaGEgPSAxLCBmYW1pbHkgPSBmYW1pbHksIG5mb2xkcz0xMDApCiAgcGxvdChjdl9tb2RlbCkgCiAgYmVzdF9tb2RlbCA8LSBnbG1uZXQoeCwgeSwgYWxwaGEgPSAxLCBmYW1pbHkgPSBmYW1pbHksIGxhbWJkYSA9IGN2X21vZGVsJGxhbWJkYS5taW4pCiAgYmVzdF9tb2RlbCRkZXYucmF0aW8KICBsYXNzb19jb2VmID0gY29lZihiZXN0X21vZGVsKSAlPiUgYXMubWF0cml4KCkgJT4lIGRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCkgJT4lIAogIHNlbGVjdChmYWN0b3I9cm93bmFtZSwgY29lZmZpY2llbnQ9czApICU+JSBmaWx0ZXIoZmFjdG9yIT0iKEludGVyY2VwdCkiKSAlPiUgCiAgYXJyYW5nZShkZXNjKGNvZWZmaWNpZW50KSkKICByZXR1cm4obGFzc29fY29lZikKfQoKbm9ybWFsaXplIDwtIGZ1bmN0aW9uKHgsIG5hLnJtID0gVFJVRSkgewogIHNjYWxlZCA9ICh4LSBtaW4oeCkpIC8obWF4KHgpLW1pbih4KSkKICAgIHJldHVybigpCn0KCmBgYAoKCgoKIyBMQVNTTyBzY2FuIHRoZSBmZWF0dXJlcwpMb29rcyBsaWtlIGl0J3MgaW1wb3J0YW50IHRvIHJlbW92ZSB0aGUgSElWIGFuZCB0cmFuc3BsYW50IGJlY2F1c2Ugb2Ygc3BhcnNpdHkgb2YgZGF0YS4KCmBgYHtyfQpzY2FuX2ZhY3RvcnMgPSBjKCdEdXJhdGlvbicsJ2FnZTE4dW5kZXInLCdhZ2U1NXBsdXMnLCdzZXgnLCdjaHJvbmljX2x1bmdfZGlzZWFzZScsCiAgICAgICAgICAgICAgICAgJ2Nocm9uaWNfbGl2ZXJfZGlzZWFzZScsICdjaHJvbmljX2tpZG5leV9kaXNlYXNlJywgJ2Nocm9uaWNfaGVhcnRfZGlzZWFzZScsIAogICAgICAgICAgICAgICAgICd0cmFuc3BsYW50X3BhdGllbnQnLCAnaGl2JywgJ2h5cGVydGVuc2lvbicsICdkaWFiZXRlcycsICdjYW5jZXInLCAnb2Jlc2l0eScsIAogICAgICAgICAgICAgICAgICdwbGFzbWEnLCAnbUFiJywgJ2FkbWl0dGVkX2hvc3BpdGFsJywndmFjY2luZV9zdGF0dXMnLAogICAgICAgICAgICAgICAgICd2b2NBbHBoYScsJ3ZvY0RlbHRhJywnY29sbGVjdGlvbl9tb250aCcsCiAgICAgICAgICAgICAgICAgJ3N1cnZlaWxsYW5jZScsJ0NUJywnbWVkaWFuX2NvdmVyYWdlJywncnVuJywgJ1BVSScpCgpzY2FsZV9zY2FuX2ZhY3RvcnMgPSBmdW5jdGlvbihwYXRpZW50X3Zhcl90bXAsIHNjYW5fZmFjdG9ycykgewogIHBfc3ViID0gcGF0aWVudF92YXJfdG1wICU+JSAKICBzZWxlY3QoTUNvVk51bWJlcixsaW5lYWdlLER1cmF0aW9uLENPTExFQ1RJT05fRFQ6bGFzdF9jb2woKSxvbmVfb2Yoc2Nhbl9mYWN0b3JzKSkgJT4lIAogIHVuaXF1ZSAlPiUgYXMuZGF0YS5mcmFtZSgpCgogIHBfc3ViWywgY29sbmFtZXMocF9zdWIpICVpbiUgc2Nhbl9mYWN0b3JzXSAKICBwX3N1Yl9zY2FsZWQgPSBwX3N1YiAlPiUgc2VsZWN0KG9uZV9vZihzY2FuX2ZhY3RvcnMpKSAlPiUgCiAgICBtdXRhdGVfaWYoaXMubnVtZXJpYywgc2NhbGUpICU+JSAjIHNjYWxlIHdpbGwgeiBzY2FsZSBpdCwgaW5zdGVhZCBvZiB0aGUgbm9ybWFsaXplIGZ4IGFib3ZlIHdoaWNoIGlzIG1pbiBtYXgKICAgIGNiaW5kKHBfc3ViICU+JSBzZWxlY3QoIW9uZV9vZihzY2FuX2ZhY3RvcnMpKSkKICByZXR1cm4ocF9zdWJfc2NhbGVkKQp9CgpwYXRpZW50X3Zhcl90bXAgPSByZWFkX2ZlYXRoZXIoInByb2Nlc3NpbmcvcGF0aWVudF92YXJfdG1wLmFycm93IikKc2Nhbl9mYWN0b3JzX3RyaW0gPSBzY2FuX2ZhY3RvcnNbIXNjYW5fZmFjdG9ycyAlaW4lIGMoInRyYW5zcGxhbnRfcGF0aWVudCIsICJoaXYiKV0gCnBfc3ViX3NjYWxlZCA9IHNjYWxlX3NjYW5fZmFjdG9ycygKICBwYXRpZW50X3Zhcl90bXAgJT4lIGZpbHRlcihuX3ZhciA8IDMwICYgQ1QgPCAyNiksIAogIHNjYW5fZmFjdG9yc190cmltKQp5PC1sb2cyKHBfc3ViX3NjYWxlZCRuX3ZhcisxKQp4PC0ocF9zdWJfc2NhbGVkWywgY29sbmFtZXMocF9zdWJfc2NhbGVkKSAlaW4lIHNjYW5fZmFjdG9yc190cmltXSkgJT4lIGRhdGEubWF0cml4KCkKbGFzc29fdW5kZXJfMzAgPSBsYXNzb194eSh4LHkpICU+JSBtdXRhdGUoY3V0b2ZmID0gIm5fdmFyX3VuZGVyXzMwIikgJT4lCiAgYXJyYW5nZShjb2VmZmljaWVudCkgJT4lIG11dGF0ZShmYWN0b3IgPSBmY3RfcmVvcmRlcihmYWN0b3IsIGNvZWZmaWNpZW50KSkKCmxhc3NvX2luaXRpYWxfZmVhdHVyZXMgPSBsYXNzb191bmRlcl8zMCAlPiUgZ2dwbG90KGFlcyh4PWZhY3RvciwgeSA9IGNvZWZmaWNpZW50KSkgKyAKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsgY29vcmRfZmxpcCgpCmxhc3NvX2luaXRpYWxfZmVhdHVyZXMKZ2dzYXZlKCJnZ3NhdmUvbGFzc29faW5pdGlhbF9mZWF0dXJlcy5wZGYiLCBsYXNzb19pbml0aWFsX2ZlYXR1cmVzLCBoZWlnaHQgPSA0LCB3aWR0aCA9IDMpCmBgYAoKYGBge3J9CmFkbWl0dGVkX21hdHJpeCA9IGNiaW5kKHgsI1t4WywiYWRtaXR0ZWRfaG9zcGl0YWwiXSA9PSAxLF0sIAogICAgICAgICAgICAgICAgICAgICAgICBuX3ZhciA9IG5vcm1hbGl6ZSh5KSkKY2xpbmljYWxfY29yX2hlYXRtYXAgPSBwaGVhdG1hcChhYnMoY29yKGFkbWl0dGVkX21hdHJpeCwgbWV0aG9kID0gInNwZWFybWFuIikpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gdmlyaWRpcygxMCksIGJvcmRlcl9jb2xvcgk9IE5BKQoKZ2dzYXZlKCJnZ3NhdmUvY2xpbmljYWxfY29yX2hlYXRtYXAucGRmIiwgY2xpbmljYWxfY29yX2hlYXRtYXAsIGhlaWdodCA9IDYsIHdpZHRoID0gNikKYGBgCgojIERlbW9uc3RyYXRlIHdoaWNoIGZlYXR1cmVzIGhhdmUgZW5vdWdoIG4gdG8gYmUgc2Nhbm5lZApgYGB7ciwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDR9CmNoZWNrX2xldmVscyA9IGZ1bmN0aW9uKHgpIHsgcmV0dXJuKGxldmVscyh4KSAlPiUgbGVuZ3RoID09MikgfQpudW1lcmljMSA9IGZ1bmN0aW9uKHgpIHsgcmV0dXJuKGFzLm51bWVyaWMoeCktMSkgfQoKcGxvdF9mZWF0dXJlX24gPSBmdW5jdGlvbihwX3N1Yl9zY2FsZWQpIHsKICBzdW1fbiA9IG5yb3cocF9zdWJfc2NhbGVkKQogIGZlYXR1cmVfc3RhdHNfSVAgPSBwX3N1Yl9zY2FsZWQgJT4lIHNlbGVjdChvbmVfb2Yoc2Nhbl9mYWN0b3JzKSkgJT4lIAogICAgZmlsdGVyKGFkbWl0dGVkX2hvc3BpdGFsID09IDEpICU+JQogICAgc2VsZWN0X2lmKGlzLmZhY3RvcikgJT4lIHNlbGVjdF9pZihjaGVja19sZXZlbHMpICU+JQogICAgbXV0YXRlX2lmKGlzLmZhY3RvciwgbnVtZXJpYzEpICU+JSBjb2xTdW1zKCkgJT4lIAogICAgZGF0YS5mcmFtZShmZWF0dXJlID0gbmFtZXMoLiksIElQID0gLikKICAgIHN1bV9uX0lQID0gZmVhdHVyZV9zdGF0c19JUFsiYWRtaXR0ZWRfaG9zcGl0YWwiLCJJUCJdCgogIAogIGZlYXR1cmVfc3RhdHNfT1AgPSBwX3N1Yl9zY2FsZWQgJT4lIHNlbGVjdChvbmVfb2Yoc2Nhbl9mYWN0b3JzKSkgJT4lIAogICAgZmlsdGVyKGFkbWl0dGVkX2hvc3BpdGFsID09IDApICU+JQogICAgc2VsZWN0X2lmKGlzLmZhY3RvcikgJT4lIHNlbGVjdF9pZihjaGVja19sZXZlbHMpICU+JQogICAgbXV0YXRlX2lmKGlzLmZhY3RvciwgbnVtZXJpYzEpICU+JSBjb2xTdW1zKCkgJT4lIAogICAgZGF0YS5mcmFtZShmZWF0dXJlID0gbmFtZXMoLiksIE9QID0gLikKICBzdW1fbl9PUCA9IHN1bV9uIC0gc3VtX25fSVAKICAKICBmZWF0dXJlX3N0YXRzID0gbGVmdF9qb2luKGZlYXR1cmVfc3RhdHNfSVAsIGZlYXR1cmVfc3RhdHNfT1ApCiAgc2xvcGUgPSBzdW1fbl9PUC9zdW1fbl9JUAogIGZlYXR1cmVfbl9wbG90ID0gZmVhdHVyZV9zdGF0cyAlPiUgZ2dwbG90KGFlcyh4ID0gSVAsIHkgPSBPUCwgbGFiZWwgPSBmZWF0dXJlKSkgKyAKICAgIGdlb21fYWJsaW5lKHNsb3BlID0gc2xvcGUsIGNvbG9yID0gInJlZCIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsgCiAgICBnZW9tX3BvaW50KCkgKyBnZW9tX3RleHRfcmVwZWwoKSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMoIGJyZWFrcyA9IHNlcSgwLDE1MDAsMTAwKSwgbGltaXRzID0gYygwLDE0MDApLAogICAgICAgICAgICAgICAgICAgICAgIHNlYy5heGlzID0gc2VjX2F4aXMofiAuIC8gc3VtX25fT1AsIGxhYmVscyA9IHNjYWxlczo6bGFiZWxfcGVyY2VudCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gc2VxKDAsMSwwLjEpKSkgKyAKICAgIHNjYWxlX3hfY29udGludW91cyggYnJlYWtzID0gc2VxKDAsMjAwMCwxMDApLCBndWlkZSA9IGd1aWRlX2F4aXMoYW5nbGUgPSA5MCksCiAgICAgICAgICAgICAgICAgICAgICAgc2VjLmF4aXMgPSBzZWNfYXhpcyh+IC4gLyBzdW1fbl9JUCwgbGFiZWxzID0gc2NhbGVzOjpsYWJlbF9wZXJjZW50KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBzZXEoMCwxLDAuMSkpKSArIHRoZW1lX3B1YnIoKSArCiAgICB4bGFiKHBhc3RlMCgiSW5wYXRpZW50IChuICYgJSBvZiAiLCBzdW1fbl9JUCwgIikiKSkgKwogICAgeWxhYihwYXN0ZTAoIk91dHBhdGllbnQgKG4gJiAlIG9mICIsIHN1bV9uX09QLCAiKSIpKQogIHJldHVybihmZWF0dXJlX25fcGxvdCkKfQoKdW5kYXRlZF9mZWF0dXJlX25fcGxvdCA9IHBsb3RfZmVhdHVyZV9uKHBfc3ViX3NjYWxlZCkKanVseW9ud2FyZHNfZmVhdHVyZV9uX3Bsb3QgPSBwbG90X2ZlYXR1cmVfbihwX3N1Yl9zY2FsZWQgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoY29sbGVjdGlvbl9kYXRlPj0iMjAyMS0wNy0wMSIpKQpmZWF0dXJlX25fcGxvdCA9IGdnYXJyYW5nZSh1bmRhdGVkX2ZlYXR1cmVfbl9wbG90ICsgZ2d0aXRsZSgiMTIvMjAyMCAtIDExLzIwMjEiKSwgCiAgICAgICAgICBqdWx5b253YXJkc19mZWF0dXJlX25fcGxvdCArIGdndGl0bGUoIjA3LzIwMjEgLSAxMS8yMDIxIiksIGFsaWduID0gImgiLAogICAgICAgICAgbGFiZWxzID0gbGlzdCgiQSIsIkIiKSkKZmVhdHVyZV9uX3Bsb3QKZ2dzYXZlKCJnZ3NhdmUvZmVhdHVyZV9uX3Bsb3QucGRmIiwgZmVhdHVyZV9uX3Bsb3QsIHdpZHRoID0gMTYsIGhlaWdodCA9IDgpCmBgYAoKIyBQTE9UVElORyBDT01NQU5EUyBQRVIgQ1QKCkVYUExPUkFUSU9OIE9GIFRIRSBBRE1JVFRFRAoKYGBge3J9CnBhdGllbnRfY291bnRzXzMwID0gcmVhZF9mZWF0aGVyKCJwcm9jZXNzaW5nL3BhdGllbnRfY291bnRzXzMwLmFycm93IikKcGF0aWVudF9jb3VudHNfMzAgPSBwYXRpZW50X2NvdW50c18zMCAlPiUgI2ZpbHRlcihjb2xsZWN0aW9uX2RhdGUgPj0iMjAyMS0wNy0wMSIpICU+JQogIG11dGF0ZShhZG1pdHRlZF9ob3NwaXRhbCA9IGFzLmZhY3RvcihhZG1pdHRlZF9ob3NwaXRhbCkpCgpjdF9kYXRlX3Bsb3QgPSBmdW5jdGlvbihwYXRpZW50X2NvdW50c18zMCwgYWRtaXR0ZWRfaG9zcGl0YWwgPSAiYWRtaXR0ZWRfaG9zcGl0YWwiKSB7CiAgcGxvdF9hZG1pdHRlZCA9IHBhdGllbnRfY291bnRzXzMwICU+JSAKICAgIGdncGxvdChhZXMoeCA9IElOU1RSVU1FTlRfUkVTVUxULCB5ID0gbl92YXIsIGNvbG9yID0gISFzeW0oYWRtaXR0ZWRfaG9zcGl0YWwpKSkgKyAKICAgIGdlb21fcG9pbnQoc2hhcGUgPSAiIikgKwogICAgICAgICAgZ2VvbV9kZW5zaXR5XzJkKGFlcyhjb2xvciA9ICEhc3ltKGFkbWl0dGVkX2hvc3BpdGFsKSkpICsgCiAgICBzdGF0X2NvcihtZXRob2QgPSAic3BlYXJtYW4iLCBjb3IuY29lZi5uYW1lID0gInJobyIpICsKICAgICAgZ2VvbV9zbW9vdGgoc2U9VFJVRSkgKyB0aGVtZV9wdWJyKCkgKyBzY2FsZV95X2NvbnRpbnVvdXModHJhbnM9ImxvZzFwIiwgCiAgICAgICAgYnJlYWtzID0gYygwLDEsMiw1LDEwLDE1LDIwLDI1LDMwKSkgKwogICAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMTAsMjYpKQogIHBsb3RfYWRtaXR0ZWRfbWFyZ2luYWxfYnlfY3QgPSBnZ01hcmdpbmFsKHBsb3RfYWRtaXR0ZWQsIHR5cGUgPSAidmlvbGluIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJhd19xdWFudGlsZXMgPSBjKDAsMC4yNSwwLjUsIDAuNzUpLAogICAgICAgICAgICAgZ3JvdXBDb2xvdXIgPSBUUlVFLCBncm91cEZpbGwgPSBUUlVFKQoKIyBCeSBEYXRlIG5vdzoKICBwbG90X2FkbWl0dGVkX2RhdGUgPSBwYXRpZW50X2NvdW50c18zMCAlPiUgZ3JvdXBfYnkoYWRtaXR0ZWRfaG9zcGl0YWwpICU+JSAKICAgIGdncGxvdChhZXMoeCA9IGNvbGxlY3Rpb25fZGF0ZSwgeSA9IG5fdmFyLCBjb2xvciA9ICEhc3ltKGFkbWl0dGVkX2hvc3BpdGFsKSkpICsgCiAgICBnZW9tX3BvaW50KHNoYXBlID0gIiIpICsKICAgICAgICAgIGdlb21fZGVuc2l0eV8yZChhZXMoY29sb3IgPSAhIXN5bShhZG1pdHRlZF9ob3NwaXRhbCkpKSArIAogICAgc3RhdF9jb3IobWV0aG9kID0gInNwZWFybWFuIiwgY29yLmNvZWYubmFtZSA9ICJyaG8iKSArCiAgICAgIGdlb21fc21vb3RoKHNlID0gVFJVRSkgKyB0aGVtZV9wdWJyKCkgKyBzY2FsZV95X2NvbnRpbnVvdXModHJhbnM9ImxvZzFwIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMCwxLDIsNSwxMCwxNSwyMCwyNSwzMCkpCiAgcGxvdF9hZG1pdHRlZF9kYXRlX21hcmdpbmFsID0gZ2dNYXJnaW5hbChwbG90X2FkbWl0dGVkX2RhdGUsICBncm91cENvbG91ciA9IFRSVUUsIGdyb3VwRmlsbCA9IFRSVUUpCiAgCiAgcGxvdF9hZG1pdHRlZF9tYXJnaW5hbF9jb21iaW5lZCA9IGdnYXJyYW5nZShwbG90X2FkbWl0dGVkX21hcmdpbmFsX2J5X2N0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3RfYWRtaXR0ZWRfZGF0ZV9tYXJnaW5hbCwgYWxpZ24gPSAiaCIpCn0KCnBsb3RfYWRtaXR0ZWRfbWFyZ2luYWxfY29tYmluZWQgPSBjdF9kYXRlX3Bsb3QocGF0aWVudF9jb3VudHNfMzAsICJhZG1pdHRlZF9ob3NwaXRhbCIpCnBsb3RfYWRtaXR0ZWRfbWFyZ2luYWxfY29tYmluZWQKCmdnc2F2ZSgiZ2dzYXZlL3Bsb3RfYWRtaXR0ZWRfbWFyZ2luYWxfY29tYmluZWQucGRmIiwgCiAgICAgICBwbG90X2FkbWl0dGVkX21hcmdpbmFsX2NvbWJpbmVkLCBoZWlnaHQgPSA0LjUsIHdpZHRoID0gOSkKYGBgCgpPVEhFUiBGQUNUT1JTCgoKYGBge3J9CiMgVkFDQ0lOQVRJT04gR1JPVVBTIEhJU1RPR1JBTQp2YWNjaW5lX2J5X2RhdGVfaGlzdCA9IHBhdGllbnRfY291bnRzXzMwICU+JSBzZWxlY3QoY29sbGVjdGlvbl9tb250aCwgdmFjY2luZV9zdGF0dXMsIGFkbWl0dGVkX2hvc3BpdGFsKSAlPiUgCiAgZmlsdGVyKHZhY2NpbmVfc3RhdHVzID09IDEpICU+JSBnZ3Bsb3QoYWVzKHggPSBjb2xsZWN0aW9uX21vbnRoKSkgKyAKICBnZW9tX2hpc3RvZ3JhbShzdGF0PSJjb3VudCIpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUsIGhqdXN0PTEpLAogICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiYmxhY2siLCBmaWxsPU5BLCBsaW5ld2lkdGggPTIpKSArCiAgeWxhYigidmFjY2luZSBjb3VudCIpCnZhY2NpbmVfYnlfZGF0ZV9oaXN0CgpnZ3NhdmUoImdnc2F2ZS92YWNjaW5lX2J5X2RhdGVfaGlzdC5wZGYiLCB2YWNjaW5lX2J5X2RhdGVfaGlzdCwgaGVpZ2h0ID0gMiwgd2lkdGggPSAyKQoKIyBBRE1JVFRFRCBHUk9VUFMgSElTVE9HUkFNCnBhdGllbnRfY291bnRzXzMwICU+JSBzZWxlY3QoY29sbGVjdGlvbl9tb250aCwgdmFjY2luZV9zdGF0dXMsIGFkbWl0dGVkX2hvc3BpdGFsKSAlPiUKICBmaWx0ZXIoYWRtaXR0ZWRfaG9zcGl0YWwgPT0gMSkgJT4lIGdncGxvdChhZXMoeCA9IGNvbGxlY3Rpb25fbW9udGgpKSArIAogIGdlb21faGlzdG9ncmFtKHN0YXQ9ImNvdW50IikKCiMgTG9hZCBpbiB0aGUgVE9UQUwgSElTVE9HUkFNCmxpbmVhZ2VzX2hpc3RvZ3JhbSA9IHJlYWRSRFMoImdnc2F2ZS9saW5lYWdlc19maWd1cmUucmRzIikKIyBjb21iaW5lIHRoZSBoaXN0b2dyYW1zCm5fdmF4X2FkbWl0ID0gcGF0aWVudF9jb3VudHNfMzAgJT4lIHNlbGVjdChDT0xMRUNUSU9OX0RULCB2YWNjaW5lX3N0YXR1cywgYWRtaXR0ZWRfaG9zcGl0YWwpICU+JQogICBtdXRhdGUobW9udGggPSBmbG9vcl9kYXRlKENPTExFQ1RJT05fRFQsICJtb250aCIpKSAlPiUgZ3JvdXBfYnkobW9udGgpICU+JQogIHN1bW1hcml6ZSh2YWNjaW5hdGVkID0gc3VtKGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHZhY2NpbmVfc3RhdHVzKSkpLCAKICAgICAgICAgICAgaG9zcGl0YWxpemVkID0gc3VtKGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGFkbWl0dGVkX2hvc3BpdGFsKSkpKSAlPiUKICAgcGl2b3RfbG9uZ2VyKCFtb250aCwgbmFtZXNfdG8gPSAidHJlbmRzIiwgdmFsdWVzX3RvID0gImNvdW50IikKCmxpbmVhZ2VzX2hpc3RvZ3JhbV92YXhfaG9zcCA9IGxpbmVhZ2VzX2hpc3RvZ3JhbSArICAKICBnZW9tX2xpbmUoZGF0YSA9IG5fdmF4X2FkbWl0LCBhZXMobW9udGgsIGNvdW50LCBjb2xvciA9IHRyZW5kcywgbGluZXR5cGUgPSB0cmVuZHMpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImdyZXkxMCIsICJibGFjayIpKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCiMgc2F2ZSB0aGUgb3V0cHV0Cmdnc2F2ZSgiZ2dzYXZlL2xpbmVhZ2VzX2hpc3RvZ3JhbV92YXhfaG9zcC5wZGYiLCBsaW5lYWdlc19oaXN0b2dyYW1fdmF4X2hvc3AsIGhlaWdodCA9IDQsIHdpZHRoID0gNCkKYGBgCgoKYGBge3J9CiMgQ1QgVkFDQ0lOQVRFRApwbG90X3ZhY2NpbmF0ZWRfbWFyZ2luYWxfYnlfY3QgPSBjdF9kYXRlX3Bsb3QocGF0aWVudF9jb3VudHNfMzAgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihjb2xsZWN0aW9uX2RhdGUgPj0iMjAyMS0wNy0wMSIgJiBhZG1pdHRlZF9ob3NwaXRhbCA9PSAxKSwgInZhY2NpbmVfc3RhdHVzIikKcGxvdF92YWNjaW5hdGVkX21hcmdpbmFsX2J5X2N0CgpnZ3NhdmUoImdnc2F2ZS9wbG90X3ZhY2NpbmF0ZWRfbWFyZ2luYWxfYnlfY3QucGRmIiwgcGxvdF92YWNjaW5hdGVkX21hcmdpbmFsX2J5X2N0LCBoZWlnaHQgPSA1LCB3aWR0aCA9IDUpCmBgYApgYGB7cn0KIyBjYW5jZXIKcGxvdF9jYW5jZXJfbWFyZ2luYWxfYnlfY3QgPSBjdF9kYXRlX3Bsb3QocGF0aWVudF9jb3VudHNfMzAgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihjb2xsZWN0aW9uX2RhdGUgPD0iMjAyMS0wNy0wMSIpLCAiY2FuY2VyIikKcGxvdF9jYW5jZXJfbWFyZ2luYWxfYnlfY3QKCnRlc3QgPSBjdF9kYXRlX3Bsb3QocGF0aWVudF9jb3VudHNfMzAsICJjYW5jZXIiKQp0ZXN0CgpgYGAKCgoKCmBgYHtyfQojIFZBQ0NJTkFUSU9OIEdST1VQUyBXSVRIIENPTlRST0wgT1ZFUiBUSEUgVElNRSAmIE9VVFBBVElFTlQgU1RBVFVTCnBsb3RfdmFjY2luYXRlZCA9IHBhdGllbnRfY291bnRzXzMwICU+JQogIGZpbHRlcihjb2xsZWN0aW9uX2RhdGU+PSIyMDIxLTA3LTAxIikgJT4lIAogIGZpbHRlcihhZG1pdHRlZF9ob3NwaXRhbCA9PSAxKSAlPiUgCiAgZ3JvdXBfYnkobUFiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gSU5TVFJVTUVOVF9SRVNVTFQsIHkgPSBuX3ZhciwgY29sb3IgPSBtQWIpKSArIAogIGdlb21fcG9pbnQoc2hhcGUgPSAiIikgKwogICAgICAgIGdlb21fZGVuc2l0eV8yZChhZXMoY29sb3IgPSBtQWIpKSArIHN0YXRfY29yKG1ldGhvZCA9ICJzcGVhcm1hbiIsIGNvci5jb2VmLm5hbWUgPSAicmhvIikgKwogICAgZ2VvbV9zbW9vdGgoc2U9VFJVRSkgKyB0aGVtZV9wdWJyKCkgKyBzY2FsZV95X2NvbnRpbnVvdXModHJhbnM9ImxvZzFwIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDAsMSwyLDUsMTAsMTUsMjAsMjUsMzApKSArCiAgICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygxMCwyNikpCgogICAgcGxvdF92YWNjaW5hdGVkX21hcmdpbmFsX2J5X2N0ID0gZ2dNYXJnaW5hbChwbG90X3ZhY2NpbmF0ZWQsIHR5cGUgPSAiYm94cGxvdCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyYXdfcXVhbnRpbGVzID0gYygwLDAuMjUsMC41LCAwLjc1KSwKICAgICAgICAgICAgIGdyb3VwQ29sb3VyID0gVFJVRSwgZ3JvdXBGaWxsID0gVFJVRSkKICAgIApwbG90X3ZhY2NpbmF0ZWRfbWFyZ2luYWxfYnlfY3QKCiNnZ3NhdmUoImdnc2F2ZS9wbG90X21BYl9tYXJnaW5hbF9ieV9jdC5wZGYiLCBwbG90X3ZhY2NpbmF0ZWRfbWFyZ2luYWxfYnlfY3QsIGhlaWdodCA9IDUsIHdpZHRoID0gNSkKYGBgCgoKIyBIZWFsdGhjYXJlIHdvcmtlcnMKYGBge3J9CiMgSENXIEdST1VQUyBXSVRIIENPTlRST0wgT1ZFUiBUSEUgVElNRSAmIE9VVFBBVElFTlQgU1RBVFVTCnRhYmxlKHBhdGllbnRfY291bnRzXzMwICU+JSAgc2VsZWN0KGFkbWl0dGVkX2hvc3BpdGFsLHN1cnZlaWxsYW5jZSkpCgpwbG90X2hjdz0gcGF0aWVudF9jb3VudHNfMzAgJT4lIGZpbHRlcihhZG1pdHRlZF9ob3NwaXRhbCA9PSAwKSAlPiUgZmlsdGVyKGNvbGxlY3Rpb25fZGF0ZT49IjIwMjEtMDctMDEiKSAlPiUKICBncm91cF9ieShzdXJ2ZWlsbGFuY2UpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBJTlNUUlVNRU5UX1JFU1VMVCwgeSA9IG5fdmFyLCBjb2xvciA9IHZhY2NpbmVfc3RhdHVzKSkgKyAKICBnZW9tX3BvaW50KHNoYXBlID0gIiIpICsKICAgICAgICBnZW9tX2RlbnNpdHlfMmQoYWVzKGNvbG9yID0gdmFjY2luZV9zdGF0dXMpKSArIAogIHN0YXRfY29yKG1ldGhvZCA9ICJzcGVhcm1hbiIsIGNvci5jb2VmLm5hbWUgPSAicmhvIikgKwogICAgZ2VvbV9zbW9vdGgoc2U9VFJVRSkgKyB0aGVtZV9wdWJyKCkgKyBzY2FsZV95X2NvbnRpbnVvdXModHJhbnM9ImxvZzFwIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDAsMSwyLDUsMTAsMTUsMjAsMjUsMzApKQooKAogIHBsb3RfaGN3X21hcmdpbmFsX2J5X2N0ID0gZ2dNYXJnaW5hbChwbG90X2hjdywgdHlwZSA9ICJ2aW9saW4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcmF3X3F1YW50aWxlcyA9IGMoMCwwLjI1LDAuNSwgMC43NSksCiAgICAgICAgICAgICBncm91cENvbG91ciA9IFRSVUUsIGdyb3VwRmlsbCA9IFRSVUUpCikpCmBgYA==